<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\services\coupon;

use app\services\BaseService;
use app\dao\coupon\CouponUserDao;
use think\exception\ValidateException;
use utils\Arr;
use exceptions\ApiException;
/**
 *
 * Class StoreCouponUserServices
 * @package app\services\coupon
 * @method useCoupon(int $id) 使用优惠券修改优惠券状态
 */
class CouponUserService extends BaseService
{
    /**
     * StoreCouponUserServices constructor.
     *
     * @param CouponUserDao $dao
     */
    public function __construct(CouponUserDao $dao)
    {
        $this->dao = $dao;
    }

    public function getCouponTypeList()
    {
        return ['0' => '满减'];
    }

    public function getUseTypeList()
    {
        return ['0' => '通用', '1' => '技师', '2' => '服务'];
    }

    public function getReceiveTypeList()
    {
        return ['1' => '新人券', '2' => '系统发送', '3' => '会员券', '4' => '积分兑换'];
    }

    public function getStatusList()
    {
        return ['0' => '未使用', '1' => '已使用', '2' => '已过期'];
    }

    /**
     * Description:获取用户领取的优惠券  后台
     *
     * @param array $where
     *
     * @throws \ReflectionException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function getUserCouponAdminList(array $where)
    {
        [$page, $limit] = $this->getPageValue();
        $data  = $this->dao->getUserCouponList($where, $page, $limit, 'id,uid,coupon_title,coupon_price,coupon_type,use_type,use_min_price,receive_type,status,create_time', [
            'user' => function ($query) {
                $query->bind(['nickname']);
            }
        ]);
        $count = $this->dao->count($where);
        return compact('data', 'count');
    }

    /**
     * 获取列表
     *
     * @param array $where
     *
     * @return array
     */
    public function issueLog(array $where)
    {
        [$page, $limit] = $this->getPageValue();
        $list = $this->dao->getList($where, 'uid,add_time', ['userInfo'], $page, $limit);
        foreach ($list as &$item) {
            $item['add_time'] = date('Y-m-d H:i:s', $item['add_time']);
        }
        $count = $this->dao->count($where);
        return compact('list', 'count');
    }

    /**
     * 获取列表
     *
     * @param array $where
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function systemPage(array $where)
    {
        /** @var CouponUserService $couponUserService */
        $couponUserService = app()->make(CouponUserService::class);
        return $couponUserService->getList($where);
    }

    /**
     * 获取用户优惠券
     *
     * @param int $id
     */
    public function getUserCouponList(int $id)
    {
        [$page, $limit] = $this->getPageValue();
        $list = $this->dao->getList(['uid' => $id], '*', ['issue'], $page, $limit);
        foreach ($list as &$item) {
            $item['_add_time'] = date('Y-m-d H:i:s', $item['add_time']);
            $item['_end_time'] = date('Y-m-d H:i:s', $item['end_time']);
        }
        $count = $this->dao->count(['uid' => $id]);
        return compact('list', 'count');
    }

    /**
     * 恢复优惠券
     *
     * @param int $id
     *
     * @return bool|mixed
     */
    public function recoverCoupon(int $id)
    {
        $status = $this->dao->value(['id' => $id], 'status');
        if ($status)
            return $this->dao->update($id, ['status' => 0, 'use_time' => '']);
        else return true;
    }

    /**
     * 过期优惠卷失效
     */
    public function checkInvalidCoupon()
    {
        $this->dao->update([['end_time', '<', time()], ['status', '=', '0']], ['status' => 2]);
    }

    /**
     * 获取用户有效优惠劵数量
     *
     * @param int $uid
     *
     * @return int
     */
    public function getUserValidCouponCount(int $uid)
    {
        $this->checkInvalidCoupon();
        return $this->dao->getCount(['uid' => $uid, 'status' => 0]);
    }

    /**
     * Description:
     *
     * @param int   $uid
     * @param int   $buyNum
     * @param array $server
     * @param int   $technicianId
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function getOrderUsableCoupon(int $uid, int $buyNum, array $server, int $technicianId = 0)
    {
        $coupons = $this->dao->queryUserAllCoupon($uid);
        foreach ($coupons as $key => $coupon) {
            switch ($coupon->use_type) {
                // 通用券
                case 0:
                    $totalPrice = bcmul((string)$buyNum, (string)$server['price']);
                    break;
                // 指定技师券
                case 1:
                    if (!$technicianId) {
                        throw new ValidateException('请选择技师！');
                    }
                    // 验证当前技师是否在优惠券使用范围
                    $useTypeId = explode(',', $coupon->use_type_id);
                    if (!in_array($technicianId, $useTypeId)) {
                        unset($coupons[$key]);
                        continue 2;
                    }
                    break;
                // 指定服务券
                case 2:
                    // 验证当前服务是否在优惠券使用范围
                    $useTypeId = explode(',', $coupon->use_type_id);
                    if (!in_array($server['id'], $useTypeId)) {
                        unset($coupons[$key]);
                        continue 2;
                    }
                    break;
            }
            if ($totalPrice < $coupon->use_min_price) {
                unset($coupons[$key]);
            }
        }
        // return object2array($coupons);
        return $coupons->toArray();
    }

    /**
     * 用户领取优惠券
     *
     * @param        $uid
     * @param        $issueCouponInfo
     * @param string $type
     *
     * @return mixed
     */
    public function addUserCoupon($uid, $issueCouponInfo, $type = 'get')
    {
        $data                  = [];
        $data['cid']           = $issueCouponInfo['id'];
        $data['uid']           = $uid;
        $data['coupon_title']  = $issueCouponInfo['title'];
        $data['coupon_price']  = $issueCouponInfo['coupon_price'];
        $data['use_min_price'] = $issueCouponInfo['use_min_price'];
        $data['add_time']      = time();
        if ($issueCouponInfo['coupon_time']) {
            $data['start_time'] = $data['add_time'];
            $data['end_time']   = $data['add_time'] + $issueCouponInfo['coupon_time'] * 86400;
        } else {
            $data['start_time'] = $issueCouponInfo['start_use_time'];
            $data['end_time']   = $issueCouponInfo['end_use_time'];
        }
        $data['type'] = $type;
        return $this->dao->save($data);
    }

    /**
     * 会员领取优惠券
     *
     * @param        $uid
     * @param        $issueCouponInfo
     * @param string $type
     *
     * @return mixed
     */
    public function addMemberUserCoupon($uid, $issueCouponInfo, $type = 'get')
    {
        $data                  = [];
        $data['cid']           = $issueCouponInfo['id'];
        $data['uid']           = $uid;
        $data['coupon_title']  = $issueCouponInfo['title'];
        $data['coupon_price']  = $issueCouponInfo['coupon_price'];
        $data['use_min_price'] = $issueCouponInfo['use_min_price'];
        $data['add_time']      = time();
        /* if ($issueCouponInfo['coupon_time']) {
             $data['start_time'] = $data['add_time'];
             $data['end_time'] = $data['add_time'] + $issueCouponInfo['coupon_time'] * 86400;
         } else {
             $data['start_time'] = $issueCouponInfo['start_use_time'];
             $data['end_time'] = $issueCouponInfo['end_use_time'];
         }*/
        $data['start_time'] = strtotime(date('Y-m-d 00:00:00', time()));
        $data['end_time']   = strtotime(date('Y-m-d 23:59:59', strtotime('+30 day')));
        $data['type']       = $type;
        return $this->dao->save($data);
    }

    /**
     * 获取用户已领取的优惠卷
     *
     * @param int $uid
     * @param     $type
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function getUserCounpon(int $uid, $type)
    {
        $where        = [];
        $where['uid'] = $uid;
        switch ($type) {
            case 0:
            case '':
                break;
            case 1:
                $where['status'] = 0;
                break;
            case 2:
                $where['status'] = 1;
                break;
            default:
                $where['status'] = 1;
                break;
        }
        [$page, $limit] = $this->getPageValue();
        $list = $this->dao->getCouponListByOrder($where, 'status ASC,add_time DESC', $page, $limit);
        return $list ? $this->tidyCouponList($list) : [];
    }

    /**
     * 格式化优惠券
     *
     * @param $couponList
     *
     * @return mixed
     */
    public function tidyCouponList($couponList)
    {
        $time = time();
        foreach ($couponList as &$coupon) {
            $coupon['use_min_price'] = number_format((float)$coupon['use_min_price'], 2);
            $coupon['coupon_price']  = number_format((float)$coupon['coupon_price'], 2);
            if ($coupon['status'] == '已使用') {
                $coupon['_type'] = 0;
                $coupon['_msg']  = '已使用';
            } elseif ($coupon['status'] == '已过期') {
                $coupon['_type'] = 0;
                $coupon['_msg']  = '已过期';
            } elseif ($coupon['end_time'] < $time) {
                $coupon['_type'] = 0;
                $coupon['_msg']  = '已过期';
            } elseif ($coupon['start_time'] > $time) {
                $coupon['_type'] = 0;
                $coupon['_msg']  = '未开始';
            } else {
                if ($coupon['start_time'] + 3600 * 24 > $time) {
                    $coupon['_type'] = 2;
                    $coupon['_msg']  = '可使用';
                } else {
                    $coupon['_type'] = 1;
                    $coupon['_msg']  = '可使用';
                }
            }
            $coupon['add_time']      = $coupon['_add_time'] = $coupon['start_time'] ? date('Y/m/d', $coupon['start_time']) : date('Y/m/d', $coupon['add_time']);
            $coupon['end_time']      = $coupon['_end_time'] = date('Y/m/d', $coupon['end_time']);
            $coupon['use_min_price'] = floatval($coupon['use_min_price']);
            $coupon['coupon_price']  = floatval($coupon['coupon_price']);
        }
        return $couponList;
    }

    /** 获取会员优惠券列表
     *
     * @param array $where
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function getMemberCoupon($uid)
    {
        if (!$uid)
            return [];
        /** @var StoreCouponIssueServices $couponIssueService */
        $couponIssueService = app()->make(StoreCouponIssueServices::class);
        //$couponWhere['status'] = 1;
        $couponWhere['receive_type'] = 4;
        //$couponWhere['is_del'] = 0;
        $couponInfo = $couponIssueService->getMemberCouponIssueList($couponWhere);
        $couponList = [];
        if ($couponInfo) {
            $couponIds  = array_column($couponInfo, 'id');
            $couponType = array_column($couponInfo, 'type', 'id');
            $couponList = $this->dao->getCouponListByOrder(['uid' => $uid, 'coupon_ids' => $couponIds], 'add_time desc');
            if ($couponList) {
                foreach ($couponList as $k => $v) {
                    $couponList[$k]['coupon_type'] = $couponIssueService->_couponType[$couponType[$v['cid']]];
                }
            }
        }
        return $couponList;
    }

    /**根据月分组看会员发放优惠券情况
     *
     * @param array $where
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function memberCouponUserGroupBymonth(array $where)
    {
        return $this->dao->memberCouponUserGroupBymonth($where);
    }

    /**会员券失效
     *
     * @param $coupon_user_id
     *
     * @return bool|mixed
     */
    public function memberCouponIsFail($coupon_user)
    {
        if (!$coupon_user)
            return false;
        if ($coupon_user['use_time'] == 0) {
            return $this->dao->update($coupon_user['id'], ['status' => 2]);
        }

    }

    /**根据id查询会员优惠劵
     *
     * @param $id
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array|bool|\think\Model|null
     */
    public function getCouponUserOne($id)
    {
        if (!$id)
            return false;
        return $this->dao->getOne(['id' => $id]);
    }

    /**根据时间查询用户优惠券
     *
     * @param array $where
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array|bool|\think\Model|null
     */
    public function getUserCounponByMonth(array $where)
    {
        if (!$where)
            return false;
        return $this->dao->getUserCounponByMonth($where);
    }

    /**
     * 检查付费会员是否领取了会员券
     *
     * @param $uid
     * @param $vipCouponIds
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function checkHave($uid, $vipCouponIds)
    {
        $list = $this->dao->getVipCouponList($uid);
        $have = [];
        foreach ($list as $item) {
            if ($vipCouponIds && in_array($item['cid'], $vipCouponIds)) {
                $have[$item['cid']] = true;
            } else {
                $have[$item['cid']] = false;
            }
        }
        return $have;
    }

    /**
     * Description:积分兑换优惠券数量
     *
     * @param array $where
     *
     * @throws \ReflectionException
     * @return mixed
     */
    public function getIntegralExchangeCouponNumber(array $where)
    {
        return $this->dao->getIntegralExchangeCouponNumber($where);
    }

    /**
     * Description:获取用户领取优惠券列表
     *
     * @param array $where
     *
     * @throws \ReflectionException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return array
     */
    public function getUserReceiveCounpon(array $where)
    {
        [$page, $limit] = $this->getPageValue();
        $data  = $this->dao->getUserReceiveCounpon($where, $page, $limit, 'id,coupon_price,coupon_type,coupon_title,start_use_time,end_use_time,status');
        $count = $this->dao->count($where);
        return compact('data', 'count');
    }
}
